package com.codedancer.campus.manager.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.UUIDGenerator;
import com.codedancer.campus.enums.CommentReportStatus;
import com.codedancer.campus.enums.SystemMessageType;
import com.codedancer.campus.manager.service.ICommentReportService;
import com.codedancer.campus.manager.service.bo.commentReport.CommentReportDisposeAddBo;
import com.codedancer.campus.manager.service.bo.commentReport.CommentReportPageSearchBo;
import com.codedancer.campus.manager.service.vo.commentReport.CommentReportPageVo;
import com.codedancer.campus.manager.service.vo.commentReport.CommentReportVo;
import com.codedancer.campus.mapper.CommentReportImageMapper;
import com.codedancer.campus.mapper.CommentReportMapper;
import com.codedancer.campus.mapper.CommentReportTypeMapper;
import com.codedancer.campus.mapper.SystemMessageMapper;
import com.codedancer.campus.mapper.UserDisabledRecordMapper;
import com.codedancer.campus.mapper.UserMapper;
import com.codedancer.campus.po.CommentReport;
import com.codedancer.campus.po.CommentReportImage;
import com.codedancer.campus.po.CommentReportType;
import com.codedancer.campus.po.SystemMessage;
import com.codedancer.campus.po.User;
import com.codedancer.campus.po.UserDisabledRecord;
import com.codedancer.campus.qo.commentReport.CommentReportPageSearchQo;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = Exception.class)
public class CommentReportServiceImpl implements ICommentReportService {

  @Autowired
  private CommentReportMapper commentReportMapper;
  @Autowired
  private UserMapper userMapper;
  @Autowired
  private CommentReportTypeMapper commentReportTypeMapper;
  @Autowired
  private CommentReportImageMapper commentReportImageMapper;
  @Autowired
  private SystemMessageMapper systemMessageMapper;
  @Autowired
  private UserDisabledRecordMapper userDisabledRecordMapper;

  /**
   * 分页查询评论举报
   *
   * @param commentReportPageSearchBo
   * @return
   */
  @Override
  public IPage<CommentReportPageVo> page(CommentReportPageSearchBo commentReportPageSearchBo) {
    CommentReportPageSearchQo commentReportPageSearchQo = BeanUtil.copyProperties(
        commentReportPageSearchBo, CommentReportPageSearchQo.class);
    IPage<CommentReport> commentReportIPage = commentReportMapper.page(
        new Page<CommentReport>(commentReportPageSearchBo.getPage(),
            commentReportPageSearchBo.getSize()), commentReportPageSearchQo);
    List<CommentReportPageVo> commentReportPageVos;
    IPage<CommentReportPageVo> commentReportPageVoIPage = new Page<>();
    commentReportPageVos = commentReportIPage.getRecords().stream().map(commentReport -> {
      CommentReportPageVo commentReportPageVo = BeanUtil.copyProperties(commentReport,
          CommentReportPageVo.class);
      User reportUser = userMapper.selectById(commentReport.getReportUserUuid());
      commentReportPageVo.setReportUserNickName(reportUser.getNickName());
      User reportedUser = userMapper.selectById(commentReport.getReportedUserUuid());
      commentReportPageVo.setReportedUserNickName(reportedUser.getNickName());
      commentReportPageVo.setReportTime(commentReport.getCreateTime());
      CommentReportType commentReportType = commentReportTypeMapper.selectById(
          commentReport.getCommentReportTypeUuid());
      commentReportPageVo.setCommentReportTypeName(commentReportType.getName());
      return commentReportPageVo;
    }).collect(Collectors.toList());
    commentReportPageVoIPage.setTotal(commentReportIPage.getTotal());
    commentReportPageVoIPage.setRecords(commentReportPageVos);
    return commentReportPageVoIPage;
  }

  /**
   * 评论举报详情
   *
   * @param uuid
   * @return
   */
  @Override
  public CommentReportVo detail(String uuid) {
    CommentReport commentReport = commentReportMapper.findById(uuid)
        .orElseThrow(() -> new BusinessException("评论举报不存在"));
    CommentReportVo commentReportVo = BeanUtil.copyProperties(commentReport, CommentReportVo.class);
    User reportUser = userMapper.selectById(commentReport.getReportUserUuid());
    commentReportVo.setReportUserNickName(reportUser.getNickName());
    User reportedUser = userMapper.selectById(commentReport.getReportedUserUuid());
    commentReportVo.setReportedUserNickName(reportedUser.getNickName());
    commentReportVo.setReportTime(commentReport.getCreateTime());
    CommentReportType commentReportType = commentReportTypeMapper.selectById(
        commentReport.getCommentReportTypeUuid());
    commentReportVo.setCommentReportTypeName(commentReportType.getName());
    // 查询举报图片
    List<CommentReportImage> commentReportImages = commentReportImageMapper.selectListByColumn(
        "comment_report_uuid", commentReport.getUuid());
    commentReportVo.setReportImages(
        commentReportImages.stream().map(CommentReportImage::getImageUrl).collect(
            Collectors.toList()));
    return commentReportVo;
  }

  /**
   * 处理存在违规
   *
   * @param commentReportDisposeAddBo
   */
  @Override
  public void disposeExistsViolation(CommentReportDisposeAddBo commentReportDisposeAddBo) {
    CommentReport commentReport = commentReportMapper.findById(
            commentReportDisposeAddBo.getCommentReportUuid())
        .orElseThrow(() -> new BusinessException("评论举报不存在"));
    commentReport.setStatus(CommentReportStatus.EXISTS_VIOLATION);
    commentReport.setExamineResult(commentReportDisposeAddBo.getExamineResult());
    commentReportMapper.updateById(commentReport);
    // 系统消息推送给相应用户
    // 1.推送给举报用户
    SystemMessage systemMessage = SystemMessage.builder()
        .uuid(UUIDGenerator.getUUID())
        .receiveUserUuid(commentReport.getReportUserUuid())
        .messageType(SystemMessageType.COMMENT_REPORT)
        .content(commentReportDisposeAddBo.getExamineResult())
        .build();
    systemMessageMapper.insert(systemMessage);
    // 2.需要推送给被举报用户，违规次数加1
    // 如果违规次数已经超过3次，用户将被禁用
    User reportedUser = userMapper.selectById(commentReport.getReportedUserUuid());
    if (reportedUser.isExceedViolationCount()) {
      // 超过3次就不需要进行推送信息
      reportedUser.setDisabled(true);
      // 保存用户禁用记录
      UserDisabledRecord userDisabledRecord = UserDisabledRecord.builder()
          .uuid(UUIDGenerator.getUUID())
          .disabledReason("该用户评论存在违规，违规次数已超3次，已被禁用")
          .userUuid(reportedUser.getUuid())
          .adminUuid(commentReportDisposeAddBo.getCurrentUserUuid()).build();
      userDisabledRecordMapper.insert(userDisabledRecord);
    } else {
      // 推送给被举报用户
      SystemMessage reportedUserSystemMessage = SystemMessage.builder()
          .messageType(SystemMessageType.COMMENT_REPORT)
          .content("你在评论中存在违规行为，对你进行警告，请遵守相关规定，否则面临账户被禁用")
          .receiveUserUuid(reportedUser.getUuid())
          .build();
      systemMessageMapper.insert(reportedUserSystemMessage);
    }
  }

  /**
   * 处理不存在违规
   *
   * @param commentReportDisposeAddBo
   */
  @Override
  public void disposeNoExistsViolation(CommentReportDisposeAddBo commentReportDisposeAddBo) {
    CommentReport commentReport = commentReportMapper.findById(
            commentReportDisposeAddBo.getCommentReportUuid())
        .orElseThrow(() -> new BusinessException("评论举报不存在"));
    commentReport.setStatus(CommentReportStatus.NOE_EXISTS_VIOLATION);
    commentReport.setExamineResult(commentReportDisposeAddBo.getExamineResult());
    commentReportMapper.updateById(commentReport);
    // 系统消息推送给相应用户
    // 推送给举报用户
    SystemMessage systemMessage = SystemMessage.builder()
        .uuid(UUIDGenerator.getUUID())
        .receiveUserUuid(commentReport.getReportUserUuid())
        .messageType(SystemMessageType.COMMENT_REPORT)
        .content(commentReportDisposeAddBo.getExamineResult())
        .build();
    systemMessageMapper.insert(systemMessage);
  }
}
